package myJs.tools

import myJs.Implicits._
import myJs.myPkg._
import myJs.myPkg.jquery._
import myJs.tool.Pojo.FilterContentData
import myJs.tool.Tool
import org.scalajs.dom._
import scalatags.Text.all._

import scala.collection.immutable.SeqMap
import scala.scalajs.js
import scala.scalajs.js.JSConverters._
import scala.scalajs.js.JSON

/**
 * Created by yz on 16/9/2021
 */
object GoResult {

  val tableId = "table"
  var tableRs: JArJDJAn = _
  val parentId = "goResult"

  def resultJq = $(s"#${parentId}")

  def init={
    registerEvent
  }

  def refreshData(rs: JDJAn) = {
    initTable(rs)
    refreshImage(rs)
  }

  def refreshImage(rs: JDJAn) = {
    val barBase64 = rs.myGet("bar")
    val enrichBase64 = rs.myGet("enrich")
    resultJq.find("#barChart").html(s"<img src='data:image/png;base64,${barBase64}' style='width:80%'>")
    resultJq.find("#enrichChart").html(s"<img src='data:image/png;base64,${enrichBase64}' style='width:80%'>")
  }

  def refreshSelect2(keys: List[String]) = {
    keys.foreach { k =>
      val inputName = k
      val data = tableRs.map(_.myGet(k)).distinct
      val array = data.map { v =>
        js.Dictionary("text" -> v, "id" -> v)
      }
      val options = Select2Options(data=array.toJSArray,multiple=true,placeholder="click to choose")
      Tool.getInputByName(inputName).mySelect2(options)
    }
  }

  def initFilterContent(tabId: String = "", map: SeqMap[String, String]) = {

    val select2Keys = map.filter { case (k, v) =>
      List("namespace").contains(v)
    }.keyList

    val rangeKeys = map.filter { case (k, v) =>
      List("p_uncorrected", "p_fdr").contains(v)
    }.keyList

    val textSortDatas = map.keyList.filterNot { x =>
      rangeKeys.contains(x)
    }.filterNot { x =>
      select2Keys.contains(x)
    }.map { fieldName =>
      FilterContentData(fieldName, map(fieldName))
    }

    val rangeSortDatas = rangeKeys.map { x =>
      FilterContentData(x, map(x))
    }

    val select2SortDatas = select2Keys.map { x =>
      FilterContentData(x, map(x), List.empty)
    }

    Tool.initFilterContent(textSortDatas = textSortDatas, rangeSortDatas = rangeSortDatas,
      select2SortDatas = select2SortDatas,
      parentId = s"${tabId}")
    refreshSelect2(select2Keys)
    textSortDatas ::: rangeSortDatas ::: select2SortDatas
  }

  def getColumnV(columnName: String, v: js.Any) = columnName match {
    case _ =>
      v.toString
  }

  def tbFmt(columnName: String, map: SeqMap[String, String]): js.Function = (v: js.Any, row: js.Dictionary[js.Any]) => {
    val header = map(columnName)
    header match {
      case x if (List("p_uncorrected", "p_fdr").contains(x)) =>
        s"${v.toDouble.toFixed(3)}"
      case _ => v
    }
  }

  def expStyle(columnName: String): js.Function = (v: js.Any, row: js.Dictionary[Any]) => columnName match {
    case _ => v
  }

  def initTable(rs: JDJAn) = {
    tableRs = rs("array").toJArJDJAn
    val map = rs("map").toJDS.toSeqMap
    val columnNames = map.keyList
    val allDatas = initFilterContent(tabId = parentId, map = map)
    val columns = columnNames.map { columnName =>
      val title = map.getOrElse(columnName, columnName)
      val fmt = tbFmt(columnName, map)
      val style = expStyle(columnName)
      val basicOptions = ColumnOptions.field(columnName).title(title).titleTooltip(title).sortable(true).
        formatter(fmt).cellStyle(style)
      columnName match {
        case x if allDatas.map(_.fieldName).contains(x) => basicOptions.
          sortable(false).operateable(true)
        case _ => basicOptions
      }
    }
    val options = TableOptions.columns(columns.toJSArray).searchOnButton(false).filterControl(false).search(true).
      data(tableRs)
    resultJq.find(s"#${tableId}").bootstrapTable(options)
    Tool.refreshCheckboxView(map.tail, resultJq.find("#checkbox"), parentId)
    val hideColumns = map.keyList.drop(6)
    hideColumns.foreach { x =>
      resultJq.find(s"#${tableId}").bootstrapTable("hideColumn", x)
      resultJq.find(s"input:checkbox[value='${x}']").attr("checked", false)
    }
  }

  def registerEvent = {
    tableFilterEvent
  }

  def tableFilterEvent = {
    Tool.clickHide

    $(document.body).on("click", s".myOperate", "", (y: Element) => {
      Tool.filterContentShow(y, parentId)
    })
    $(document.body).on("click", s".mySortLi", "", (y: Element) => {
      Tool.execSort(y, parentId, () => {
        refreshTable
      })
    })
    $(document.body).on("click", s".myConfirm", "", (y: Element) => {
      Tool.confirmFilter(y, parentId, () => {
        refreshTable
      })
    })
    $(document.body).on("click", s".myHide", "", (y: Element) => {
      Tool.hideFilterContent(y)
    })
    $(document.body).on("click", s".myRemove", "", (y: Element) => {
      Tool.removeCondition(y, parentId, () => {
        refreshTable
      })
    })
    $(document.body).on("click", s".myRemoveSort", "", (y: Element) => {
      Tool.removeSort(y, parentId, () => {
        refreshTable
      })
    })
  }

  def refreshTable: Any = {
    refreshTable(() => ())
  }

  def refreshTable(f: () => Any): Any = {
    val queryMap = Tool.getQueryMap("")
    val sortData = Tool.sortExec(tableRs, queryMap)
    val filterData = Tool.execFilter(sortData = sortData, queryMap = queryMap, getColumnV = getColumnV)
    resultJq.find(s"#${tableId}").bootstrapTable("load", filterData)
    f()
  }

}
